const jwt = require('jsonwebtoken');
const { Op } = require('sequelize');
const { Admin, Role, Permission, AdminRole, RolePermission } = require('../models');
const logger = require('../utils/logger');

class AdminService {
  /**
   * 管理员登录
   */
  async login(username, password, ip) {
    try {
      // 查找管理员
      const admin = await Admin.findOne({
        where: {
          username: username
        },
        include: [{
          model: Role,
          as: 'roles',
          include: [{
            model: Permission,
            as: 'permissions'
          }]
        }]
      });

      if (!admin) {
        throw new Error('管理员账户不存在');
      }

      // 检查账户状态
      if (admin.status === 'inactive') {
        throw new Error('账户已被禁用');
      }

      if (admin.isLocked()) {
        throw new Error('账户已被锁定，请稍后再试');
      }

      // 验证密码
      const isValidPassword = await admin.verifyPassword(password);
      if (!isValidPassword) {
        await admin.incrementLoginFails();
        throw new Error('密码错误');
      }

      // 重置登录失败次数
      await admin.resetLoginFails();

      // 更新登录信息
      admin.lastLoginAt = new Date();
      admin.lastLoginIp = ip;
      await admin.save();

      // 整理权限列表
      const permissions = [];
      admin.roles.forEach(role => {
        role.permissions.forEach(permission => {
          if (!permissions.find(p => p.id === permission.id)) {
            permissions.push({
              id: permission.id,
              name: permission.name,
              resource: permission.resource,
              action: permission.action
            });
          }
        });
      });

      // 生成JWT token
      const token = jwt.sign(
        {
          id: admin.id,
          username: admin.username,
          type: 'admin'
        },
        process.env.JWT_SECRET,
        { expiresIn: '24h' }
      );

      return {
        token,
        admin: {
          id: admin.id,
          username: admin.username,
          email: admin.email,
          realName: admin.realName,
          avatar: admin.avatar,
          roles: admin.roles.map(role => ({
            id: role.id,
            name: role.name,
            displayName: role.displayName
          })),
          permissions
        }
      };
    } catch (error) {
      logger.error('Admin login failed:', error);
      throw error;
    }
  }

  /**
   * 创建管理员
   */
  async createAdmin(adminData, creatorId) {
    try {
      const { username, email, phone, password, realName, roleIds } = adminData;

      // 检查用户名是否已存在
      const existingAdmin = await Admin.findOne({
        where: { username }
      });

      if (existingAdmin) {
        throw new Error('用户名已存在');
      }

      // 检查邮箱是否已存在
      if (email) {
        const existingEmail = await Admin.findOne({
          where: { email }
        });

        if (existingEmail) {
          throw new Error('邮箱已存在');
        }
      }

      // 创建管理员
      const admin = await Admin.create({
        username,
        email,
        phone,
        password,
        realName,
        createdBy: creatorId
      });

      // 分配角色
      if (roleIds && roleIds.length > 0) {
        const roleAssignments = roleIds.map(roleId => ({
          adminId: admin.id,
          roleId: roleId,
          assignedBy: creatorId
        }));

        await AdminRole.bulkCreate(roleAssignments);
      }

      return admin;
    } catch (error) {
      logger.error('Create admin failed:', error);
      throw error;
    }
  }

  /**
   * 获取管理员列表
   */
  async getAdminList(options = {}) {
    try {
      const {
        page = 1,
        limit = 20,
        search,
        status,
        roleId
      } = options;

      const where = {};
      
      if (search) {
        where[Op.or] = [
          { username: { [Op.like]: `%${search}%` } },
          { email: { [Op.like]: `%${search}%` } },
          { realName: { [Op.like]: `%${search}%` } }
        ];
      }

      if (status) {
        where.status = status;
      }

      const include = [{
        model: Role,
        as: 'roles',
        attributes: ['id', 'name', 'displayName']
      }];

      if (roleId) {
        include[0].where = { id: roleId };
      }

      const { count, rows } = await Admin.findAndCountAll({
        where,
        include,
        attributes: { exclude: ['password'] },
        limit: parseInt(limit),
        offset: (parseInt(page) - 1) * parseInt(limit),
        order: [['createdAt', 'DESC']]
      });

      return {
        admins: rows,
        pagination: {
          current: parseInt(page),
          total: Math.ceil(count / limit),
          pageSize: parseInt(limit),
          totalItems: count
        }
      };
    } catch (error) {
      logger.error('Get admin list failed:', error);
      throw error;
    }
  }

  /**
   * 获取管理员详情
   */
  async getAdminById(adminId) {
    try {
      const admin = await Admin.findByPk(adminId, {
        attributes: { exclude: ['password'] },
        include: [{
          model: Role,
          as: 'roles',
          include: [{
            model: Permission,
            as: 'permissions'
          }]
        }]
      });

      if (!admin) {
        throw new Error('管理员不存在');
      }

      return admin;
    } catch (error) {
      logger.error('Get admin by id failed:', error);
      throw error;
    }
  }

  /**
   * 更新管理员信息
   */
  async updateAdmin(adminId, updateData, updaterId) {
    try {
      const admin = await Admin.findByPk(adminId);
      
      if (!admin) {
        throw new Error('管理员不存在');
      }

      const { username, email, phone, realName, status, roleIds } = updateData;

      // 检查用户名是否已被其他管理员使用
      if (username && username !== admin.username) {
        const existingAdmin = await Admin.findOne({
          where: { 
            username,
            id: { [Op.ne]: adminId }
          }
        });

        if (existingAdmin) {
          throw new Error('用户名已存在');
        }
      }

      // 检查邮箱是否已被其他管理员使用
      if (email && email !== admin.email) {
        const existingEmail = await Admin.findOne({
          where: { 
            email,
            id: { [Op.ne]: adminId }
          }
        });

        if (existingEmail) {
          throw new Error('邮箱已存在');
        }
      }

      // 更新基本信息
      await admin.update({
        username: username || admin.username,
        email: email || admin.email,
        phone: phone || admin.phone,
        realName: realName || admin.realName,
        status: status || admin.status,
        updatedBy: updaterId
      });

      // 更新角色分配
      if (roleIds !== undefined) {
        // 删除现有角色
        await AdminRole.destroy({
          where: { adminId }
        });

        // 分配新角色
        if (roleIds.length > 0) {
          const roleAssignments = roleIds.map(roleId => ({
            adminId,
            roleId,
            assignedBy: updaterId
          }));

          await AdminRole.bulkCreate(roleAssignments);
        }
      }

      return admin;
    } catch (error) {
      logger.error('Update admin failed:', error);
      throw error;
    }
  }

  /**
   * 删除管理员
   */
  async deleteAdmin(adminId, deleterId) {
    try {
      const admin = await Admin.findByPk(adminId);
      
      if (!admin) {
        throw new Error('管理员不存在');
      }

      // 不能删除自己
      if (adminId === deleterId) {
        throw new Error('不能删除自己的账户');
      }

      // 删除角色关联
      await AdminRole.destroy({
        where: { adminId }
      });

      // 删除管理员
      await admin.destroy();

      return true;
    } catch (error) {
      logger.error('Delete admin failed:', error);
      throw error;
    }
  }

  /**
   * 重置管理员密码
   */
  async resetPassword(adminId, newPassword, operatorId) {
    try {
      const admin = await Admin.findByPk(adminId);
      
      if (!admin) {
        throw new Error('管理员不存在');
      }

      await admin.update({
        password: newPassword,
        updatedBy: operatorId
      });

      return true;
    } catch (error) {
      logger.error('Reset admin password failed:', error);
      throw error;
    }
  }

  /**
   * 检查管理员权限
   */
  async checkPermission(adminId, resource, action) {
    try {
      const admin = await Admin.findByPk(adminId, {
        include: [{
          model: Role,
          as: 'roles',
          include: [{
            model: Permission,
            as: 'permissions',
            where: {
              resource,
              action,
              status: 'active'
            }
          }]
        }]
      });

      if (!admin) {
        return false;
      }

      // 检查是否有匹配的权限
      for (const role of admin.roles) {
        if (role.permissions.length > 0) {
          return true;
        }
      }

      return false;
    } catch (error) {
      logger.error('Check admin permission failed:', error);
      return false;
    }
  }
}

module.exports = new AdminService();